home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
fish
/
001-100
/
001-025
/
008
/
src
/
hack.vault.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-17
|
5KB
|
216 lines
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
#include "hack.h"
#ifdef QUEST
setgd(/* mtmp */) /* struct monst *mtmp; */ {}
gd_move() { return(2); }
gddead(mtmp) struct monst *mtmp; {}
invault(){}
#else
extern struct monst *makemon();
#define VAULT 6
#define FCSIZ (ROWNO+COLNO)
struct fakecorr {
xchar fx,fy,ftyp;
};
struct egd {
int fcbeg, fcend; /* fcend: first unused pos */
xchar gdx, gdy; /* goal of guard's walk */
unsigned gddone:1;
struct fakecorr fakecorr[FCSIZ];
};
struct permonst pm_guard =
{ "guard", '@', 12, 12, -1, 4, 10, sizeof(struct egd) };
struct monst *guard;
int gdlevel;
#define EGD ((struct egd *)(&(guard->mextra[0])))
restfakecorr(){
register int fcx,fcy,fcbeg;
register struct rm *crm;
while((fcbeg = EGD->fcbeg) < EGD->fcend) {
fcx = EGD->fakecorr[fcbeg].fx;
fcy = EGD->fakecorr[fcbeg].fy;
if((u.ux == fcx && u.uy == fcy) || cansee(fcx,fcy) ||
m_at(fcx,fcy))
return;
crm = &levl[fcx][fcy];
crm->typ = EGD->fakecorr[fcbeg].ftyp;
if(!crm->typ) crm->seen = 0;
newsym(fcx,fcy);
EGD->fcbeg++;
}
/* it seems he left the corridor - let the guard disappear */
mondead(guard);
guard = 0;
}
setgd(){
register struct monst *mtmp;
for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->isgd){
guard = mtmp;
gdlevel = dlevel;
return;
}
guard = 0;
}
invault(){
register int tmp = inroom(u.ux, u.uy);
if(tmp < 0 || rooms[tmp].rtype != VAULT) {
u.uinvault = 0;
return;
}
if(++u.uinvault % 50 == 0 && (!guard || gdlevel != dlevel)) {
char buf[BUFSZ];
register int x,y,dx,dy,gx,gy;
/* first find the goal for the guard */
for(dy = 0; dy < ROWNO; dy++)
for(y = u.uy-dy; y <= u.uy+dy; y++) {
if(y > u.uy-dy) y = u.uy+dy;
if(y < 0 || y > ROWNO-1) continue;
for(x = u.ux; x < COLNO; x++)
if(levl[x][y].typ == CORR) goto fnd;
for(x = u.ux-1; x > 0; x--)
if(levl[x][y].typ == CORR) goto fnd;
}
impossible();
tele();
return;
fnd:
gx = x; gy = y;
/* next find a good place for a door in the wall */
x = u.ux; y = u.uy;
while(levl[x][y].typ > DOOR) {
dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
if(abs(gx-x) >= abs(gy-y)) x += dx;
else y += dy;
}
/* make something interesting happen */
if(!(guard = makemon(&pm_guard,x,y))) return;
guard->isgd = guard->mpeaceful = 1;
EGD->gddone = 0;
gdlevel = dlevel;
if(!cansee(guard->mx, guard->my)) {
mondead(guard);
guard = 0;
return;
}
EGD->gdx = gx;
EGD->gdy = gy;
EGD->fcbeg = 0;
EGD->fakecorr[0].fx = x;
EGD->fakecorr[0].fy = y;
EGD->fakecorr[0].ftyp = levl[x][y].typ;
levl[x][y].typ = DOOR;
EGD->fcend = 1;
pline("Suddenly one of the Vault's guards enters!");
pmon(guard);
pline("\"Hello stranger, who are you?\" - ");
getlin(buf);
clrlin();
pline("\"I don't know you.\"");
if(!u.ugold) pline("\"Please follow me.\"");
else {
pline("\"Most likely all that gold was stolen from this vault.\"");
pline("\"Please drop your gold (say d$ ) and follow me.\"");
}
}
}
gd_move(){
register int x,y,dx,dy,gx,gy,nx,ny,tmp;
register struct fakecorr *fcp;
register struct rm *crm;
if(!guard || gdlevel != dlevel){
pline("Where is the guard?");
impossible();
return(2); /* died */
}
if(u.ugold || dist(guard->mx,guard->my) > 2 || EGD->gddone){
restfakecorr();
return(0); /* didnt move */
}
x = guard->mx;
y = guard->my;
/* look around (hor & vert only) for accessible places */
for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++)
if(nx == x || ny == y) if(nx != x || ny != y)
if(isok(nx,ny))
if((tmp = (crm = &levl[nx][ny])->typ) >= SDOOR) {
register int i;
for(i = EGD->fcbeg; i < EGD->fcend; i++)
if(EGD->fakecorr[i].fx == nx &&
EGD->fakecorr[i].fy == ny)
goto nextnxy;
if((i = inroom(nx,ny)) >= 0 && rooms[i].rtype == VAULT)
goto nextnxy;
/* seems we found a good place to leave him alone */
EGD->gddone = 1;
if(tmp >= DOOR) goto newpos;
crm->typ = (tmp == SCORR) ? CORR : DOOR;
goto proceed;
nextnxy: ;
}
nx = x;
ny = y;
gx = EGD->gdx;
gy = EGD->gdy;
dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy;
while((tmp = (crm = &levl[nx][ny])->typ) != 0) {
/* in view of the above we must have tmp < SDOOR */
/* must be a wall here */
if(isok(nx+nx-x,ny+ny-y) && levl[nx+nx-x][ny+ny-y].typ > DOOR){
crm->typ = DOOR;
goto proceed;
}
if(dy && nx != x) {
nx = x; ny = y+dy; dx = 0;
continue;
}
if(dx && ny != y) {
ny = y; nx = x+dx; dy = 0;
continue;
}
/* I don't like this, but ... */
crm->typ = DOOR;
goto proceed;
}
crm->typ = CORR;
proceed:
fcp = &(EGD->fakecorr[EGD->fcend]);
if(EGD->fcend++ == FCSIZ) panic("fakecorr overflow");
fcp->fx = nx;
fcp->fy = ny;
fcp->ftyp = tmp;
newpos:
if(EGD->gddone) nx = ny = 0;
guard->mx = nx;
guard->my = ny;
pmon(guard);
restfakecorr();
return(1);
}
gddead(){
guard = 0;
}
#endif QUEST